﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using AutoFix.ClientComponents;
using AutoFix.Interfaces;
using BusinessLogicLayer.Manager;
using Common;
using Objects;

namespace AutoFix
{
    public partial class Main : System.Web.UI.MasterPage, IMaster
    {
        #region [IMaster Implementations]

        /// <summary>
        /// Gets or sets a value indicating whether [is login page].
        /// </summary>
        /// <value>
        ///   <c>true</c> if [is login page]; otherwise, <c>false</c>.
        /// </value>
        public bool IsLoginPage
        {
            get { return (this.ViewState[Constants.WebApp.ViewState.IsLoginPage] != null) ? Convert.ToBoolean(this.ViewState[Constants.WebApp.ViewState.IsLoginPage]) : false; }
            private set { this.ViewState[Constants.WebApp.ViewState.IsLoginPage] = value; }
        }

        /// <summary>
        /// Gets or sets a value indicating whether [is anonymous page].
        /// </summary>
        /// <value>
        ///   <c>true</c> if [is anonymous page]; otherwise, <c>false</c>.
        /// </value>
        public bool IsAnonymousPage
        {
            get { return (this.ViewState[Constants.WebApp.ViewState.IsAnonymousPage] != null) ? Convert.ToBoolean(this.ViewState[Constants.WebApp.ViewState.IsAnonymousPage]) : false; }
            private set { this.ViewState[Constants.WebApp.ViewState.IsAnonymousPage] = value; }
        }
        /// <summary>
        ///  Gets or sets a value indicating the name of user logged in.
        /// </summary>
        public string LoginPersonName
        {
            get { return this.lblLoginPerson.Text; }
            private set { this.lblLoginPerson.Text = value; }
        }

        /// <summary>
        /// Initializes the security policy.
        /// </summary>
        /// <param name="isLoginPage">if set to <c>true</c> [is login page].</param>
        /// <param name="isAnonymousPage">if set to <c>true</c> [is anonymous page].</param>
        /// <param name="pageName">Name of the page.</param>
        /// <param name="authorizedUserTypes">Authorized User Types</param>
        public void InitializeSecurityPolicy(bool isLoginPage, bool isAnonymousPage, string pageName, List<UserType> authorizedUserTypes)
        {
            this.IsLoginPage = isLoginPage;
            this.IsAnonymousPage = isAnonymousPage;
            this.pageNameControl.PageNameText = pageName ?? string.Empty;

            //...session is available, proceed with authorization.
            //  Apply authorization rules, deny access for unuthorized users.
            //
            User user = this.PageSession.ApplicationUser;
            UserType userType = UserType.None;
            //
            //  Check is the user is in login page
            //  All users are allowed to access the login page, bypass security rules
            //
            if (isLoginPage == false)
            {
                //  ...current page is not the login page.
                //  Verify if the current page is a public page
                //
                if (isAnonymousPage == true)
                {
                    //...current page is a public page.
                    //  Verify if any user session is available
                    //
                    if (this.PageSession.ApplicationUser == null)
                    {
                        //...user session is unavailable.
                        //  Initializes an annonymous session and grant access
                        //
                        this.InitializeAnonymousSession();
                        //
                        //  Sets the welcome note
                        //                        
                        this.PrepareWelcomeNote(user);

                        this.navigation1.UserType = UserType.Guest;

                    }
                    else
                    {
                        this.PrepareWelcomeNote(user);

                        userType = (UserType)user.UserTypeID;
                        if (userType == UserType.Admin)
                        {
                            this.navigation1.UserType = UserType.Admin;
                        }
                        if (userType == UserType.Contributor)
                        {
                            this.navigation1.UserType = UserType.Contributor;
                        }
                        if (userType == UserType.Guest)
                        {
                            this.navigation1.UserType = UserType.Guest;
                        }
                    }

                    return;
                }
                else
                {
                    //...page is not an annonymous page, authorization is required.
                    //  Veryfy if the session is available to proceed with authorization rules.
                    //
                    if (this.PageSession.ApplicationUser == null)
                    {
                        //...session is unavailable.
                        //  Redirect user to login page for authentication.
                        //
                        FormsAuthentication.RedirectToLoginPage();
                        this.navigation1.UserType = UserType.Guest;
                    }
                    else
                    {
                        userType = (UserType)user.UserTypeID;

                        if (authorizedUserTypes.Contains(userType) == false)
                        {
                            //...current user is not allowed to access this page.
                            //  Redirect unauthorized users to default home page (public page)
                            //
                            Response.Redirect(FormsAuthentication.DefaultUrl, false);


                        }
                        else
                        {
                            //
                            //  Sets the welcome note
                            //
                            this.PrepareWelcomeNote(user);
                            if (userType == UserType.Admin)
                            {
                                this.navigation1.UserType = UserType.Admin;
                            }
                            if (userType == UserType.Contributor)
                            {
                                this.navigation1.UserType = UserType.Contributor;
                            }
                        }
                    }

                    return;
                }
            }
            else
            {
                this.navigation1.UserType = UserType.Guest;
            }
        }

        #endregion

        #region [Private Members]

        /// <summary>
        /// The page session
        /// </summary>
        private AppSession PageSession = new AppSession();



        #endregion

        #region [Event Handlers]

        /// <summary>
        /// Handles the Load event of the Page control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
        protected void Page_Load(object sender, EventArgs e)
        {

        }
        /// <summary>
        /// Handles the click event of the logout button.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
        protected void lnkLogOut_Click(object sender, EventArgs e)
        {
            this.PageSession.ApplicationUser = null;
            FormsAuthentication.RedirectToLoginPage();
        }

        #endregion

        #region [Private Methods]

        /// <summary>
        /// Initializes the anonymous session.
        /// </summary>
        private void InitializeAnonymousSession()
        {
            string userName = AppConfiguration.AnonymousUserName;
            string password = Encryption.Encrypt(AppConfiguration.AnonymousUserPassword);

            UserManager manager = new UserManager();
            User user = manager.AuthenticateUser(userName, password);

            if (user == null)
            {
                return;
            }

            this.PageSession.ApplicationUser = user;

            LoginPersonName = this.PageSession.ApplicationUser.FirstName;

            FormsAuthenticationTicket authTicket = new FormsAuthenticationTicket(1,
                                                        userName,
                                                        DateTime.Now,
                                                        DateTime.Now.AddMinutes(30),
                                                        false,
                                                        null);

            string authCookieStr = FormsAuthentication.Encrypt(authTicket);
            HttpCookie authCookie = new HttpCookie(FormsAuthentication.FormsCookieName, authCookieStr);

            authCookie.Expires = authTicket.Expiration;
            authCookie.Path = FormsAuthentication.FormsCookiePath;
            Response.Cookies.Add(authCookie);
        }
        /// <summary>
        /// Prepares the welcome note.
        /// </summary>
        /// <param name="user">The user.</param>
        private void PrepareWelcomeNote(User user)
        {
            try
            {
                string welcomeNote = string.Empty;
                this.lblWelcome.Visible = false;
                this.lblLoginPerson.Visible = false;

                if (user != null)
                {
                    this.lnkLogOut.Visible = true;
                    this.lblWelcome.Visible = true;
                    this.lblLoginPerson.Visible = true;

                    UserType userType = (UserType)user.UserTypeID;
                    string roleLabel = this.GetRoleLabel(userType);

                    roleLabel = (string.IsNullOrEmpty(roleLabel) == true) ? string.Empty : string.Format(@"({0})", roleLabel);

                    welcomeNote = string.Format(" {0} {1}", user.FirstName, roleLabel);
                }

                this.lblLoginPerson.Text = welcomeNote;
            }
            catch (Exception eX)
            {
            }
        }

        /// <summary>
        /// Gets the role label.
        /// </summary>
        /// <param name="userType">Type of the user.</param>
        /// <returns>the name of the role</returns>
        private string GetRoleLabel(UserType userType)
        {
            string roleLabel = string.Empty;

            switch (userType)
            {
                case UserType.Guest:
                    {
                        roleLabel = Constants.WebApp.Common.Guest;
                        break;
                    }
                case UserType.Admin:
                    {
                        roleLabel = Constants.WebApp.Common.Admin;
                        break;
                    }
                case UserType.Contributor:
                    {
                        roleLabel = Constants.WebApp.Common.Contributor;
                        break;
                    }
                default:
                    break;
            }

            return roleLabel;
        }

        #endregion



    }
}
